//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package genreqcmd

import (
	"fmt"
	"os"

	"atomgit.com/openlinksaas-org/grpcutil/utils"
	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
	"github.com/jhump/protoreflect/desc"
	"github.com/spf13/cobra"
	"google.golang.org/protobuf/types/descriptorpb"
)

var inputFile = ""
var serviceName = ""
var methodName = ""

var GenReqCommand = &cobra.Command{
	Use: "genReq",
	RunE: func(cmd *cobra.Command, args []string) error {
		return runGenReqCommand()
	},
}

func runGenReqCommand() error {
	data, err := os.ReadFile(inputFile)
	if err != nil {
		return err
	}
	descSet := &descriptorpb.FileDescriptorSet{}
	err = proto.Unmarshal(data, descSet)
	if err != nil {
		return err
	}

	unresolved := map[string]*descriptorpb.FileDescriptorProto{}
	for _, fd := range descSet.File {
		unresolved[fd.GetName()] = fd
	}
	resolved := map[string]*desc.FileDescriptor{}
	for _, fd := range descSet.File {
		_, err := utils.ResolveFileDescriptor(unresolved, resolved, fd.GetName())
		if err != nil {
			return err
		}
	}

	var reqType *desc.MessageDescriptor
	for _, fd := range resolved {
		svc := fd.FindService(serviceName)
		if svc == nil {
			continue
		}
		method := svc.FindMethodByName(methodName)
		if method == nil {
			continue
		}
		reqType = method.GetInputType()
		break
	}
	if reqType == nil {
		return fmt.Errorf("unkown service or method")
	}
	m := utils.MakeTemplate(reqType)
	marshler := &jsonpb.Marshaler{
		EmitDefaults: true,
		Indent:       " ",
	}
	jsonStr, err := marshler.MarshalToString(m)
	if err != nil {
		return err
	}
	fmt.Print(jsonStr)
	return nil
}

func init() {
	GenReqCommand.Flags().StringVar(&inputFile, "in", "", "proto parse info file")
	GenReqCommand.Flags().StringVar(&serviceName, "service", "", "service name")
	GenReqCommand.Flags().StringVar(&methodName, "method", "", "method name")
}
